using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Ammo : MonoBehaviour, IFireable
{
    #region Tooltip

    [Tooltip("使用子 TrailRenderer 组件填充")]

    #endregion Tooltip

    [SerializeField]
    private TrailRenderer trailRenderer;

    private float ammoRange = 0f; // 每种弹药的射程
    private float ammoSpeed;
    private Vector3 fireDirectionVector;
    private float fireDirectionAngle;
    private SpriteRenderer spriteRenderer;
    private AmmoDetailsSO ammoDetails;
    private float ammoChargeTimer;
    private bool isAmmoMaterialSet = false;
    private bool overrideAmmoMovement;
    private bool isColliding = false;

    private void Awake()
    {
        // 缓存精灵渲染器
        spriteRenderer = GetComponent<SpriteRenderer>();
    }

    private void Update()
    {
        // 弹药装药效果
        if (ammoChargeTimer > 0f)
        {
            ammoChargeTimer -= Time.deltaTime;
            return;
        }
        else if (!isAmmoMaterialSet)
        {
            SetAmmoMaterial(ammoDetails.ammoMaterial);
            isAmmoMaterialSet = true;
        }
        
        // 如果移动已被覆盖，请不要移动弹药 - 例如，此弹药是弹药模式的一部分
        if (!overrideAmmoMovement)
        {
            // 计算移动弹药的距离向量
            Vector3 distanceVector = fireDirectionVector * ammoSpeed * Time.deltaTime;

            transform.position += distanceVector;

            // 达到最大范围后禁用
            ammoRange -= distanceVector.magnitude;

            if (ammoRange < 0f)
            {
                if (ammoDetails.isPlayerAmmo)
                {
                    // 无乘数
                    StaticEventHandler.CallMultiplierEvent(false);
                }

                DisableAmmo();
            }
        }
    }
    
    private void OnTriggerEnter2D(Collider2D collision)
    {
        // 如果已经与某物发生碰撞，请返回
        if (isColliding) return;
        
        // 对碰撞物体造成伤害
        DealDamage(collision);
        
        // 显示弹药命中效果
        AmmoHitEffect();
        
        DisableAmmo();
    }
    
    private void DealDamage(Collider2D collision)
    {
        Health health = collision.GetComponent<Health>();

        bool enemyHit = false;
        
        if (health != null)
        {
            // 设置 isColliding 以防止弹药多次造成伤害
            isColliding = true;
            
            health.TakeDamage(ammoDetails.ammoDamage);
            
            // 敌人命中
            if (health.enemy != null)
            {
                enemyHit = true;
            }
        }
        
        // 如果玩家弹药，则更新乘数
        if (ammoDetails.isPlayerAmmo)
        {
            if (enemyHit)
            {
                // 乘数
                StaticEventHandler.CallMultiplierEvent(true);
            }
            else
            {
                // 无乘数
                StaticEventHandler.CallMultiplierEvent(false);
            }
        }
    }
    
    /// <summary>
    /// 初始化正在发射的弹药 - 使用 ammodetails、aimangle、weaponAngle 和
    /// weaponAimDirectionVector。如果此弹药是模式的一部分，则弹药运动可以是
    /// 通过将 overrideAmmoMovement 设置为 true 来覆盖
    /// </summary>
    public void InitialiseAmmo(AmmoDetailsSO ammoDetails, float aimAngle, float weaponAimAngle, float ammoSpeed,
        Vector3 weaponAimDirectionVector, bool overrideAmmoMovement = false)
    {
        #region Ammo

        this.ammoDetails = ammoDetails;

        // 初始化 isColliding
        isColliding = false;

        // 设置开火方向
        SetFireDirection(ammoDetails, aimAngle, weaponAimAngle, weaponAimDirectionVector);

        // 设置开会精灵组件
        spriteRenderer.sprite = ammoDetails.ammoSprite;

        // 根据是否有弹药充能期设置初始弹药材料
        if (ammoDetails.ammoChargeTime > 0f)
        {
            // 设置弹药充能计时器
            ammoChargeTimer = ammoDetails.ammoChargeTime;
            SetAmmoMaterial(ammoDetails.ammoChargeMaterial);
            isAmmoMaterialSet = false;
        }
        else
        {
            ammoChargeTimer = 0f;
            SetAmmoMaterial(ammoDetails.ammoMaterial);
            isAmmoMaterialSet = true;
        }

        // 设置弹药射程
        ammoRange = ammoDetails.ammoRange;

        // 设置弹药速度
        this.ammoSpeed = ammoSpeed;

        // 覆盖弹药移动
        this.overrideAmmoMovement = overrideAmmoMovement;

        // 激活弹药游戏对象
        gameObject.SetActive(true);

        #endregion Ammo
        
        #region Trail

        if (ammoDetails.isAmmoTrail)
        {
            trailRenderer.gameObject.SetActive(true);
            trailRenderer.emitting = true;
            trailRenderer.material = ammoDetails.ammoTrailMaterial;
            trailRenderer.startWidth = ammoDetails.ammoTrailStartWidth;
            trailRenderer.endWidth = ammoDetails.ammoTrailEndWidth;
            trailRenderer.time = ammoDetails.ammoTrailTime;
        }
        else
        {
            trailRenderer.emitting = false;
            trailRenderer.gameObject.SetActive(false);
        }

        #endregion Trail
    }
    
    /// <summary>
    /// 根据调整后的输入角度和方向设置弹药射击方向和角度
    /// 随机点差
    /// </summary>
    private void SetFireDirection(AmmoDetailsSO ammoDetails, float aimAngle, float weaponAimAngle, Vector3 weaponAimDirectionVector)
    {
        // 计算最小值和最大值之间的随机散布角
        float randomSpread = Random.Range(ammoDetails.ammoSpreadMin, ammoDetails.ammoSpreadMax);

        // 获取 1 或 -1 的随机点差切换
        int spreadToggle = Random.Range(0, 2) * 2 - 1;

        if (weaponAimDirectionVector.magnitude < Settings.useAimAngleDistance)
        {
            fireDirectionAngle = aimAngle;
        }
        else
        {
            fireDirectionAngle = weaponAimAngle;
        }

        // 通过随机散布调整弹药射击角度
        fireDirectionAngle += spreadToggle * randomSpread;

        // 设置弹药轮换
        transform.eulerAngles = new Vector3(0f, 0f, fireDirectionAngle);

        // 设置弹药射击方向
        fireDirectionVector = HelperUtilities.GetDirectionVectorFromAngle(fireDirectionAngle);

    }

    /// <summary>
    /// 禁用弹药 - 从而将其返回到对象池
    /// </summary>
    private void DisableAmmo()
    {
        gameObject.SetActive(false);
    }
    
    /// <summary>
    /// 显示弹药命中效果
    /// </summary>
    private void AmmoHitEffect()
    {
        // 如果指定了命中效果，则进行处理
        if (ammoDetails.ammoHitEffect != null && ammoDetails.ammoHitEffect.ammoHitEffectPrefab != null)
        {
            // 从池中获取弹药命中效果游戏对象（带有粒子系统组件）
            AmmoHitEffect ammoHitEffect = (AmmoHitEffect)PoolManager.Instance.ReuseComponent(ammoDetails.ammoHitEffect.ammoHitEffectPrefab, transform.position, Quaternion.identity);

            // 设置命中效果
            ammoHitEffect.SetHitEffect(ammoDetails.ammoHitEffect);

            // 将游戏对象设置为活动（粒子系统设置为自动禁用
            // gameobject 一旦完成）
            ammoHitEffect.gameObject.SetActive(true);
        }
    }
    
    public void SetAmmoMaterial(Material material)
    {
        spriteRenderer.material = material;
    }

    public GameObject GetGameObject()
    {
        return gameObject;
    }

    #region Validation
#if UNITY_EDITOR

    private void OnValidate()
    {
        HelperUtilities.ValidateCheckNullValue(this, nameof(trailRenderer), trailRenderer);
    }

#endif
    #endregion Validation
}